{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "| [05_text_matching/02_句粒度文本匹配.ipynb](https://github.com/shibing624/nlp-tutorial/tree/main/05_text_matching/02_句粒度文本匹配.ipynb)  | SentenceBert的句子相似度计算  |[Open In Colab](https://colab.research.google.com/github/shibing624/nlp-tutorial/blob/main/05_text_matching/02_句粒度文本匹配.ipynb) |\n",
    "\n",
    "# 句子文本相似度计算\n",
    "\n",
    "1. word2vec词相似度取均值计算句子相似度\n",
    "2. sentence bert计算句子相似度\n",
    "3. SimCSE计算句子相似度"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# word2vec词相似度取均值计算句子相似度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'新浪': 0,\n",
       " '中国': 1,\n",
       " '化妆品': 2,\n",
       " '美国': 3,\n",
       " '广告': 4,\n",
       " '碎片': 5,\n",
       " '计划': 6,\n",
       " '地球': 7,\n",
       " '销售': 8,\n",
       " '上市': 9,\n",
       " '5月': 10,\n",
       " '科学家': 11,\n",
       " '皮肤': 12,\n",
       " '改善': 13,\n",
       " '大学': 14,\n",
       " '的产品': 15,\n",
       " '市场': 16,\n",
       " '彗星': 17,\n",
       " '财务': 18,\n",
       " '预计': 19,\n",
       " '参与': 20,\n",
       " '网站': 21,\n",
       " '兼任': 22,\n",
       " '提供': 23,\n",
       " '瓦斯': 24,\n",
       " '高科技公司': 25,\n",
       " '73p': 26,\n",
       " '负责': 27,\n",
       " '植物': 28,\n",
       " '拿了': 29,\n",
       " '2005年': 30,\n",
       " '1999': 31,\n",
       " '距离': 32,\n",
       " '硕士': 33,\n",
       " '首席': 34,\n",
       " '2000': 35,\n",
       " '年度': 36,\n",
       " '10': 37,\n",
       " '报道': 38,\n",
       " '银行': 39,\n",
       " '担任': 40,\n",
       " '推出': 41,\n",
       " '便宜': 42,\n",
       " '之间': 43,\n",
       " '人民币': 44,\n",
       " '2005': 45,\n",
       " '亿元': 46,\n",
       " '商业': 47,\n",
       " '推动': 48,\n",
       " 'cfo': 49,\n",
       " '12日': 50,\n",
       " '宇航局': 51,\n",
       " '互联网': 52,\n",
       " '海外': 53,\n",
       " '上海': 54,\n",
       " '首次': 55,\n",
       " '很有': 56,\n",
       " '3号': 57,\n",
       " '德州': 58,\n",
       " '奥斯汀': 59,\n",
       " '再到': 60,\n",
       " '赴美': 61,\n",
       " '新闻学': 62,\n",
       " '奥克拉荷': 63,\n",
       " '电视台': 64,\n",
       " '先在': 65,\n",
       " '求学': 66,\n",
       " '当了': 67,\n",
       " '两年': 68,\n",
       " '记者': 69,\n",
       " '那一': 70,\n",
       " '专业': 71,\n",
       " '副总裁': 72,\n",
       " '照搬': 73,\n",
       " '变了': 74,\n",
       " '2001': 75,\n",
       " '2001年': 76,\n",
       " '借鉴': 77,\n",
       " '中国概念股': 78,\n",
       " '余家': 79,\n",
       " '结构': 80,\n",
       " '公司': 81,\n",
       " '设计': 82,\n",
       " '运作': 83,\n",
       " '加盟': 84,\n",
       " '身份': 85,\n",
       " '多家': 86,\n",
       " '转入': 87,\n",
       " '在此期间': 88,\n",
       " '咨询': 89,\n",
       " '服务': 90,\n",
       " '审计': 91,\n",
       " '地区': 92,\n",
       " '工作': 93,\n",
       " '普华永道': 94,\n",
       " '1993': 95,\n",
       " '注册会计师': 96,\n",
       " '协会': 97,\n",
       " '会计师': 98,\n",
       " '早就': 99,\n",
       " '企业界': 100,\n",
       " '硅谷': 101,\n",
       " '同学': 102,\n",
       " '大学毕业': 103,\n",
       " '相关': 104,\n",
       " '市场分析': 105,\n",
       " '人士': 106,\n",
       " '监管部门': 107,\n",
       " '阻力': 108,\n",
       " '考虑到': 109,\n",
       " '交易': 110,\n",
       " '高昂': 111,\n",
       " 'macquarie': 112,\n",
       " '固定成本': 113,\n",
       " '可能是': 114,\n",
       " '最低': 115,\n",
       " '金额': 116,\n",
       " '原本': 117,\n",
       " '2006': 118,\n",
       " '此项': 119,\n",
       " '资金': 120,\n",
       " '将是': 121,\n",
       " '批准': 122,\n",
       " '有关部门': 123,\n",
       " '证券化': 124,\n",
       " '资产': 125,\n",
       " '贷款': 126,\n",
       " '抵押': 127,\n",
       " '住房': 128,\n",
       " 'arie': 129,\n",
       " 'acq': 130,\n",
       " '澳大利亚': 131,\n",
       " '昨日': 132,\n",
       " '媒体': 133,\n",
       " '国外': 134,\n",
       " '发自': 135,\n",
       " '年初': 136,\n",
       " 'anda': 137,\n",
       " '计划性': 138,\n",
       " '相貌端正': 139,\n",
       " '才是': 140,\n",
       " '特长': 141,\n",
       " '2,复旦': 142,\n",
       " '本报记者': 143,\n",
       " '杨国强': 144,\n",
       " '1984年': 145,\n",
       " '复旦大学': 146,\n",
       " '房地产': 147,\n",
       " '新闻系': 148,\n",
       " '回忆说': 149,\n",
       " '内向': 150,\n",
       " '做事': 151,\n",
       " '生活': 152,\n",
       " '学习': 153,\n",
       " '资本运作': 154,\n",
       " '投融资': 155,\n",
       " '项目': 156,\n",
       " '金融机构': 157,\n",
       " '竟是': 158,\n",
       " '行列': 159,\n",
       " '开发商': 160,\n",
       " '此前': 161,\n",
       " '执行官': 162,\n",
       " '投资': 163,\n",
       " '基金': 164,\n",
       " '房地产投资': 165,\n",
       " '该银行': 166,\n",
       " '否决': 167,\n",
       " '证监会': 168,\n",
       " '香港特区': 169,\n",
       " '投资信托': 170,\n",
       " '网络广告': 171,\n",
       " '这一': 172,\n",
       " '方式': 173,\n",
       " '很可能': 174,\n",
       " '角质化': 175,\n",
       " '过程': 176,\n",
       " '所需': 177,\n",
       " '时间': 178,\n",
       " '三个月': 179,\n",
       " '会把': 180,\n",
       " '理想': 181,\n",
       " '安全地': 182,\n",
       " '预期': 183,\n",
       " '短期': 184,\n",
       " '都是': 185,\n",
       " '加了': 186,\n",
       " '违禁': 187,\n",
       " '原料': 188,\n",
       " '虽然在': 189,\n",
       " '表皮': 190,\n",
       " '状况': 191,\n",
       " '3,化妆品': 192,\n",
       " '利用': 193,\n",
       " '月球': 194,\n",
       " '20': 195,\n",
       " '多倍': 196,\n",
       " '不会有': 197,\n",
       " '危险': 198,\n",
       " '提醒': 199,\n",
       " '会对': 200,\n",
       " 'n101': 201,\n",
       " '观察': 202,\n",
       " '中最': 203,\n",
       " '明亮': 204,\n",
       " '双筒望远镜': 205,\n",
       " '肉眼': 206,\n",
       " '观察到': 207,\n",
       " '天内': 208,\n",
       " '导致': 209,\n",
       " '最接近': 210,\n",
       " '皮肤病': 211,\n",
       " '成分': 212,\n",
       " '也许': 213,\n",
       " '发现': 214,\n",
       " '相差无几': 215,\n",
       " '配方': 216,\n",
       " '选购': 217,\n",
       " '简单': 218,\n",
       " '办法': 219,\n",
       " '尝试': 220,\n",
       " '检测': 221,\n",
       " '合格': 222,\n",
       " '品牌': 223,\n",
       " '选择': 224,\n",
       " '不良反应': 225,\n",
       " '感觉': 226,\n",
       " '对照': 227,\n",
       " '越好': 228,\n",
       " '质量': 229,\n",
       " '出售': 230,\n",
       " '2.': 231,\n",
       " '绿色': 232,\n",
       " '作成': 233,\n",
       " '形态': 234,\n",
       " '装在': 235,\n",
       " '瓶子': 236,\n",
       " '不可能': 237,\n",
       " '3.': 238,\n",
       " '不含': 239,\n",
       " '防腐剂': 240,\n",
       " '化学成分': 241,\n",
       " '迷信': 242,\n",
       " '纯天然': 243,\n",
       " '宣传': 244,\n",
       " '轨道': 245,\n",
       " '即便是': 246,\n",
       " '改为': 247,\n",
       " '增长率': 248,\n",
       " '并购': 249,\n",
       " '无线': 250,\n",
       " '后来居上': 251,\n",
       " '稳定的': 252,\n",
       " '利润': 253,\n",
       " '2004年': 254,\n",
       " '6月': 255,\n",
       " '联席': 256,\n",
       " '营长': 257,\n",
       " '运营': 258,\n",
       " '部门': 259,\n",
       " '重组': 260,\n",
       " '进了': 261,\n",
       " '系统化': 262,\n",
       " '管理体系': 263,\n",
       " '两次': 264,\n",
       " '谈判': 265,\n",
       " '主持': 266,\n",
       " '主和': 267,\n",
       " '符合': 268,\n",
       " '广告主': 269,\n",
       " '需求': 270,\n",
       " '时段': 271,\n",
       " '流量': 272,\n",
       " '模式': 273,\n",
       " '客户': 274,\n",
       " '2003年': 275,\n",
       " '肯定': 276,\n",
       " '最舒服': 277,\n",
       " '举措': 278,\n",
       " '领先地位': 279,\n",
       " '奠定': 280,\n",
       " '基础': 281,\n",
       " '业绩': 282,\n",
       " '年来': 283,\n",
       " '28日': 284,\n",
       " '超过': 285,\n",
       " '4月': 286,\n",
       " '27日': 287,\n",
       " '14日': 288,\n",
       " '30': 289,\n",
       " '史无前例': 290,\n",
       " '对此': 291,\n",
       " '反驳': 292,\n",
       " '撞击': 293,\n",
       " '更不': 294,\n",
       " '会引起': 295,\n",
       " '大规模': 296,\n",
       " '海啸': 297,\n",
       " '生物': 298,\n",
       " '灭绝': 299,\n",
       " '灾难': 300,\n",
       " '太空': 301,\n",
       " '2,美国': 302,\n",
       " 'ceo': 303,\n",
       " '杰出': 304,\n",
       " '竞争对手': 305,\n",
       " '博客': 306,\n",
       " '发展计划': 307,\n",
       " '赢得了': 308,\n",
       " '新浪博客': 309,\n",
       " '成功': 310,\n",
       " '影响力': 311,\n",
       " '10日': 312,\n",
       " '人物': 313,\n",
       " '荣誉': 314,\n",
       " '9月': 315,\n",
       " '升任': 316,\n",
       " '裁并': 317,\n",
       " '2006年': 318,\n",
       " '1,本报记者': 319}"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import gensim\n",
    "import numpy as np\n",
    "import jieba\n",
    "txt_path = 'data/C000008_test.txt'\n",
    "sentences = [i.split() for i in open(txt_path, 'r', encoding='utf-8').read().split('\\n')]\n",
    "model = gensim.models.Word2Vec(\n",
    "    sentences, vector_size=50, window=5, min_count=1, workers=4)\n",
    "model.wv.key_to_index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.07167525"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.wv.similarity('中国', '澳大利亚')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def encode(model, sentences):\n",
    "    all_embeddings = []\n",
    "    for sentence in sentences:\n",
    "        emb = []\n",
    "        count = 0\n",
    "        for word in jieba.cut(sentence):\n",
    "            # 调用词向量\n",
    "            if word in model.wv.key_to_index:\n",
    "                emb.append(model.wv.get_vector(word, norm=True))\n",
    "                count += 1\n",
    "            else:\n",
    "                if len(word) == 1:\n",
    "                    continue\n",
    "                \n",
    "        tensor_x = np.array(emb).sum(axis=0)  # 纵轴相加\n",
    "        if count > 0:\n",
    "            avg_tensor_x = np.divide(tensor_x, count)\n",
    "        else:\n",
    "            avg_tensor_x = 0.0\n",
    "        all_embeddings.append(avg_tensor_x)\n",
    "    all_embeddings = np.array(all_embeddings)\n",
    "    return all_embeddings\n",
    "\n",
    "\n",
    "def try_divide(x, y, val=0.0):\n",
    "    \"\"\"\n",
    "    try to divide two numbers\n",
    "    \"\"\"\n",
    "    if y != 0.0:\n",
    "        val = float(x) / y\n",
    "    return val\n",
    "\n",
    "\n",
    "def cosine_distance(v1, v2):\n",
    "    \"\"\"\n",
    "    余弦距离\n",
    "    return cos score\n",
    "    \"\"\"\n",
    "    up = float(np.sum(v1 * v2))\n",
    "    down = np.linalg.norm(v1) * np.linalg.norm(v2)\n",
    "    return try_divide(up, down)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Building prefix dict from the default dictionary ...\n",
      "Loading model from cache /var/folders/my/wtb78vc53sv_jjmg5pk2j1_c0000gn/T/jieba.cache\n",
      "Loading model cost 0.602 seconds.\n",
      "Prefix dict has been built successfully.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[-0.21927972,  0.11965213, -0.11060282,  0.02288989,  0.2286874 ,\n",
       "        -0.12062721,  0.12260447, -0.1796113 , -0.09880254,  0.25282925,\n",
       "        -0.04210246,  0.00750591, -0.10957509, -0.20485967, -0.04109238,\n",
       "         0.06779569, -0.02187172,  0.14667678, -0.07604338,  0.05980942,\n",
       "         0.14544745,  0.22526506, -0.03795141, -0.24797286,  0.11825557,\n",
       "         0.01711099,  0.19830742, -0.02212599, -0.07319297, -0.2348599 ,\n",
       "        -0.02186776,  0.07873122,  0.14362314,  0.1910106 , -0.15462022,\n",
       "         0.05368754,  0.16605844, -0.12769549, -0.08349914,  0.18038665,\n",
       "         0.04792265,  0.00571483,  0.09246843,  0.00772719,  0.26039112,\n",
       "         0.13504699, -0.23830333, -0.19043949,  0.02728905,  0.1714201 ]],\n",
       "      dtype=float32)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "e1 = encode(model, ['我爱中国'])\n",
    "e1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.08764014,  0.08764137, -0.06243022, -0.11438316, -0.08762652,\n",
       "        -0.14942485,  0.08534562, -0.18681532, -0.1828148 , -0.10902873,\n",
       "         0.17930381,  0.04311304,  0.1324419 ,  0.1992213 , -0.15120956,\n",
       "        -0.11115517,  0.18666913,  0.11929383,  0.11192316,  0.2174516 ,\n",
       "         0.21221076, -0.06500908,  0.02543302,  0.13279945,  0.21533124,\n",
       "         0.23973903, -0.20145756, -0.12415431,  0.12015305,  0.02245801,\n",
       "         0.00361878,  0.18243577,  0.1549656 , -0.17490093, -0.06315232,\n",
       "        -0.20450875,  0.17221251,  0.06680533, -0.05411964,  0.04456296,\n",
       "         0.18637545,  0.19693525,  0.14924552,  0.07730085,  0.03876383,\n",
       "         0.19705747,  0.03150117,  0.00986437, -0.22979966,  0.06114372]],\n",
       "      dtype=float32)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "e2 = encode(model, ['你是在澳大利亚吧'])\n",
    "e2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.07167525589466095"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cos_score = cosine_distance(e1, e2)\n",
    "cos_score"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# sentence bert计算句子相似度\n",
    "使用transformers模型（如Bert）来获取句子向量，然后计算句子相似度值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "!pip install -qU transformers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \"purple is the best city in the forest\"\n",
    "b = \"there is an art to getting your way and throwing bananas on to the street is not it\"  # this is very similar to 'g'\n",
    "c = \"it is not often you find soggy bananas on the street\"\n",
    "d = \"green should have smelled more tranquil but somehow it just tasted rotten\"\n",
    "e = \"joyce enjoyed eating pancakes with ketchup\"\n",
    "f = \"as the asteroid hurtled toward earth becky was upset her dentist appointment had been canceled\"\n",
    "g = \"to get your way you must not bombard the road with yellow fruit\"  # this is very similar to 'b'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "from transformers import AutoTokenizer, AutoModel\n",
    "import torch\n",
    "import os\n",
    "os.environ[\"KMP_DUPLICATE_LIB_OK\"]=\"TRUE\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "基于预训练SBERT模型加载HF transformer模型和tokenizer切词器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "BertModel(\n",
       "  (embeddings): BertEmbeddings(\n",
       "    (word_embeddings): Embedding(30522, 768, padding_idx=0)\n",
       "    (position_embeddings): Embedding(512, 768)\n",
       "    (token_type_embeddings): Embedding(2, 768)\n",
       "    (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "    (dropout): Dropout(p=0.1, inplace=False)\n",
       "  )\n",
       "  (encoder): BertEncoder(\n",
       "    (layer): ModuleList(\n",
       "      (0): BertLayer(\n",
       "        (attention): BertAttention(\n",
       "          (self): BertSelfAttention(\n",
       "            (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "          (output): BertSelfOutput(\n",
       "            (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "        (intermediate): BertIntermediate(\n",
       "          (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "        )\n",
       "        (output): BertOutput(\n",
       "          (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "      (1): BertLayer(\n",
       "        (attention): BertAttention(\n",
       "          (self): BertSelfAttention(\n",
       "            (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "          (output): BertSelfOutput(\n",
       "            (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "        (intermediate): BertIntermediate(\n",
       "          (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "        )\n",
       "        (output): BertOutput(\n",
       "          (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "      (2): BertLayer(\n",
       "        (attention): BertAttention(\n",
       "          (self): BertSelfAttention(\n",
       "            (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "          (output): BertSelfOutput(\n",
       "            (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "        (intermediate): BertIntermediate(\n",
       "          (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "        )\n",
       "        (output): BertOutput(\n",
       "          (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "      (3): BertLayer(\n",
       "        (attention): BertAttention(\n",
       "          (self): BertSelfAttention(\n",
       "            (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "          (output): BertSelfOutput(\n",
       "            (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "        (intermediate): BertIntermediate(\n",
       "          (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "        )\n",
       "        (output): BertOutput(\n",
       "          (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "      (4): BertLayer(\n",
       "        (attention): BertAttention(\n",
       "          (self): BertSelfAttention(\n",
       "            (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "          (output): BertSelfOutput(\n",
       "            (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "        (intermediate): BertIntermediate(\n",
       "          (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "        )\n",
       "        (output): BertOutput(\n",
       "          (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "      (5): BertLayer(\n",
       "        (attention): BertAttention(\n",
       "          (self): BertSelfAttention(\n",
       "            (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "          (output): BertSelfOutput(\n",
       "            (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "        (intermediate): BertIntermediate(\n",
       "          (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "        )\n",
       "        (output): BertOutput(\n",
       "          (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "      (6): BertLayer(\n",
       "        (attention): BertAttention(\n",
       "          (self): BertSelfAttention(\n",
       "            (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "          (output): BertSelfOutput(\n",
       "            (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "        (intermediate): BertIntermediate(\n",
       "          (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "        )\n",
       "        (output): BertOutput(\n",
       "          (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "      (7): BertLayer(\n",
       "        (attention): BertAttention(\n",
       "          (self): BertSelfAttention(\n",
       "            (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "          (output): BertSelfOutput(\n",
       "            (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "        (intermediate): BertIntermediate(\n",
       "          (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "        )\n",
       "        (output): BertOutput(\n",
       "          (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "      (8): BertLayer(\n",
       "        (attention): BertAttention(\n",
       "          (self): BertSelfAttention(\n",
       "            (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "          (output): BertSelfOutput(\n",
       "            (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "        (intermediate): BertIntermediate(\n",
       "          (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "        )\n",
       "        (output): BertOutput(\n",
       "          (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "      (9): BertLayer(\n",
       "        (attention): BertAttention(\n",
       "          (self): BertSelfAttention(\n",
       "            (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "          (output): BertSelfOutput(\n",
       "            (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "        (intermediate): BertIntermediate(\n",
       "          (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "        )\n",
       "        (output): BertOutput(\n",
       "          (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "      (10): BertLayer(\n",
       "        (attention): BertAttention(\n",
       "          (self): BertSelfAttention(\n",
       "            (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "          (output): BertSelfOutput(\n",
       "            (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "        (intermediate): BertIntermediate(\n",
       "          (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "        )\n",
       "        (output): BertOutput(\n",
       "          (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "      (11): BertLayer(\n",
       "        (attention): BertAttention(\n",
       "          (self): BertSelfAttention(\n",
       "            (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "          (output): BertSelfOutput(\n",
       "            (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "        (intermediate): BertIntermediate(\n",
       "          (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "        )\n",
       "        (output): BertOutput(\n",
       "          (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "    )\n",
       "  )\n",
       "  (pooler): BertPooler(\n",
       "    (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "    (activation): Tanh()\n",
       "  )\n",
       ")"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tokenizer = AutoTokenizer.from_pretrained('sentence-transformers/bert-base-nli-mean-tokens')\n",
    "model = AutoModel.from_pretrained('sentence-transformers/bert-base-nli-mean-tokens')\n",
    "model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "句子切分："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "odict_keys(['last_hidden_state', 'pooler_output'])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tokens = tokenizer([a, b, c, d, e, f, g],\n",
    "                   max_length=128,\n",
    "                   truncation=True,\n",
    "                   padding='max_length',\n",
    "                   return_tensors='pt')\n",
    "\n",
    "\n",
    "outputs = model(**tokens)\n",
    "outputs.keys()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们看下最后一层 embedding, *last_hidden_state*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[-0.6239, -0.2058,  0.0411,  ...,  0.1490,  0.5681,  0.2381],\n",
       "         [-0.3694, -0.1485,  0.3780,  ...,  0.4204,  0.5553,  0.1441],\n",
       "         [-0.7221, -0.3813,  0.2031,  ...,  0.0761,  0.5162,  0.2813],\n",
       "         ...,\n",
       "         [-0.1894, -0.3711,  0.3034,  ...,  0.1536,  0.3265,  0.1376],\n",
       "         [-0.2496, -0.5227,  0.2341,  ...,  0.3419,  0.3164,  0.0256],\n",
       "         [-0.3311, -0.4430,  0.3492,  ...,  0.3655,  0.2910,  0.0728]],\n",
       "\n",
       "        [[ 0.6052, -0.0735, -0.5481,  ...,  0.7239, -0.4543,  0.5766],\n",
       "         [ 0.8756,  0.1283, -0.1134,  ...,  1.0779, -0.6687,  0.1533],\n",
       "         [ 0.6438, -0.1035, -0.0356,  ...,  1.0527, -0.5948,  0.3460],\n",
       "         ...,\n",
       "         [ 0.5072, -0.3408, -0.4086,  ...,  0.2983, -0.4924,  0.1635],\n",
       "         [ 0.6438, -0.4270, -0.4055,  ...,  0.4219, -0.6627,  0.3300],\n",
       "         [ 0.5080, -0.3873, -0.4192,  ...,  0.4467, -0.6076, -0.0204]],\n",
       "\n",
       "        [[ 0.3746, -0.6272, -0.1954,  ...,  1.2944,  0.0382, -0.1495],\n",
       "         [ 0.0991, -0.5104, -0.2070,  ...,  1.3102, -0.1638, -0.4281],\n",
       "         [ 0.1719, -0.5110,  0.0178,  ...,  1.2745, -0.1528, -0.4197],\n",
       "         ...,\n",
       "         [ 0.2985, -0.8965, -0.2273,  ...,  1.3782, -0.1252, -0.3914],\n",
       "         [ 0.2063, -0.7767, -0.2481,  ...,  1.2427, -0.2184, -0.3437],\n",
       "         [ 0.2768, -0.8227, -0.2103,  ...,  1.2217, -0.2406, -0.2931]],\n",
       "\n",
       "        ...,\n",
       "\n",
       "        [[-0.9127,  0.3013, -0.2805,  ...,  0.2136,  0.9626,  0.1324],\n",
       "         [-1.1195,  0.5118, -0.2762,  ...,  0.1485,  0.8387, -0.3362],\n",
       "         [-0.6343,  0.2643,  0.0567,  ...,  0.4709,  0.9775,  0.0474],\n",
       "         ...,\n",
       "         [-0.6487,  0.2804, -0.0451,  ...,  0.3814,  0.3789,  0.1517],\n",
       "         [-0.7960,  0.3996, -0.0456,  ...,  0.3656,  0.3514,  0.1730],\n",
       "         [-0.9778,  0.5661, -0.0472,  ...,  0.2571,  0.2866,  0.1826]],\n",
       "\n",
       "        [[-0.4012,  0.6096,  0.6357,  ..., -0.1940,  0.2564,  0.1841],\n",
       "         [-0.4901,  0.6399,  0.6290,  ..., -0.5239, -0.0513, -0.0564],\n",
       "         [-0.4559,  1.0928,  0.1474,  ..., -0.6870,  0.2443, -0.3370],\n",
       "         ...,\n",
       "         [-0.2566,  0.1330,  0.9556,  ...,  0.3746,  0.0698,  0.7191],\n",
       "         [-0.3043,  0.2345,  0.9297,  ...,  0.1644,  0.2202,  0.6252],\n",
       "         [-0.2804,  0.2757,  0.9949,  ...,  0.2467,  0.1800,  0.7017]],\n",
       "\n",
       "        [[ 0.6347,  0.6689,  0.8165,  ...,  0.6807, -1.0780,  0.5755],\n",
       "         [ 0.6713,  0.8964,  0.7105,  ...,  0.2664, -1.4301,  0.7115],\n",
       "         [ 0.1664,  0.3910,  0.8319,  ...,  0.4466, -1.5852,  0.4205],\n",
       "         ...,\n",
       "         [ 0.2224,  0.4128,  0.2703,  ...,  0.2827, -0.9855, -0.2421],\n",
       "         [ 0.2291,  0.4047,  0.3200,  ...,  0.3043, -0.9822, -0.2921],\n",
       "         [ 0.2094,  0.3191,  0.6544,  ...,  0.5458, -1.0013, -0.0659]]],\n",
       "       grad_fn=<NativeLayerNormBackward>)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "embeddings = outputs.last_hidden_state\n",
    "embeddings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "mask = tokens['attention_mask'].unsqueeze(-1).expand(embeddings.size()).float()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "两者shape一致，可以做mask掩码操作："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[-0.6239, -0.2058,  0.0411,  ...,  0.1490,  0.5681,  0.2381],\n",
       "        [-0.3694, -0.1485,  0.3780,  ...,  0.4204,  0.5553,  0.1441],\n",
       "        [-0.7221, -0.3813,  0.2031,  ...,  0.0761,  0.5162,  0.2813],\n",
       "        ...,\n",
       "        [-0.0000, -0.0000,  0.0000,  ...,  0.0000,  0.0000,  0.0000],\n",
       "        [-0.0000, -0.0000,  0.0000,  ...,  0.0000,  0.0000,  0.0000],\n",
       "        [-0.0000, -0.0000,  0.0000,  ...,  0.0000,  0.0000,  0.0000]],\n",
       "       grad_fn=<SelectBackward>)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "masked_embeddings = embeddings * mask\n",
    "masked_embeddings[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在列维度加和，取得768维向量："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([7, 768])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "summed = torch.sum(masked_embeddings, 1)\n",
    "summed.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，在需要做attention的位置设置为+1，不需要的位置设置为+0."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([7, 768])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "counted = torch.clamp(mask.sum(1), min=1e-9)\n",
    "counted.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后，得到均值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([7, 768])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_pooled = summed / counted\n",
    "mean_pooled.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这样得到了句向量，句子间两两计算相似度："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "from sklearn.metrics.pairwise import cosine_similarity\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# convert to numpy array from torch tensor\n",
    "mean_pooled = mean_pooled.detach().numpy()\n",
    "\n",
    "# calculate similarities (will store in array)\n",
    "scores = np.zeros((mean_pooled.shape[0], mean_pooled.shape[0]))\n",
    "for i in range(mean_pooled.shape[0]):\n",
    "    scores[i, :] = cosine_similarity(\n",
    "        [mean_pooled[i]],\n",
    "        mean_pooled\n",
    "    )[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.00000024,  0.18692753,  0.28297687,  0.29628235,  0.27451012,\n",
       "         0.1017626 ,  0.21696253],\n",
       "       [ 0.18692753,  1.        ,  0.72058773,  0.5142895 ,  0.11749641,\n",
       "         0.1930692 ,  0.66182351],\n",
       "       [ 0.28297687,  0.72058773,  1.00000012,  0.48864433,  0.2356894 ,\n",
       "         0.17157128,  0.5599308 ],\n",
       "       [ 0.29628235,  0.5142895 ,  0.48864433,  0.99999976,  0.26985487,\n",
       "         0.3788943 ,  0.52388817],\n",
       "       [ 0.27451012,  0.11749642,  0.23568939,  0.2698549 ,  0.99999994,\n",
       "         0.23422128, -0.01599788],\n",
       "       [ 0.10176259,  0.1930692 ,  0.17157127,  0.37889427,  0.23422126,\n",
       "         1.00000012,  0.22319673],\n",
       "       [ 0.21696255,  0.66182345,  0.5599308 ,  0.52388811, -0.01599788,\n",
       "         0.22319674,  0.99999994]])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "scores"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 展示SBERT的句子相似度结果"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用 `matplotlib` 可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<AxesSubplot:>"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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zB8QW6tWBCt+n0fVqpXxeDw8/O97ad2mO4cPH+GRYc8z9ZP/EhISzJ49+xlc4Nh2Ys8RdmdmznYsw9ka1vCWsvrendHPx6LPXKgMa1OuVqBDCKiqBAc6hIAavzqgydaAG9LxiUCHEDDTYuzzocdXXNkH/TonZnz92336t/bx/dMDMsfHts9JERERkVyBnCbsS3osvoiIiJRKyqSIiIjYnL5gUERERMSPlEkRERGxubI6Q0WZFBERESmVlEkRERGxOU8ZzaUokyIiIiKlkjIpIiIiNqfZPSIiIiJ+pEyKiIiIzZXNESnKpIiIiEgppUyKiIiIzWlMioiIiIgfKZMiIiJic2X1W5DVSREREbE5PcxNRERExI+USREREbG5splHUSZFRERESillUkRERGxOU5BFRERE/EiZFBEREZvT7B4RERERP1ImRURExObKZh5FmRQREREppZRJERERsTnN7hERERHxI2VSREREbE6ze0RERET8SJkUERERmyubeRQ/dFIWHd3r6/+i1GpcrkagQwioGHdmoEMIqG5WeKBDCKghHZ8IdAgBNWX1a4EOIWByOjwe6BCkjFAmRURExOY0u0dERETEj5RJERERsTmrjI5KUSZFRERESiVlUkRERGxOY1JERERE/EiZFBEREZsrq0+cVSdFRETE5spmF0W3e0RERKSUUiZFRETE5srq7R5lUkRERKRUUiZFRETE5jQFWURERMSPlEkRERGxOT0WX0RERMSPlEkRERGxOY1JEREREfEjZVJERERsTmNSRERERPxImRQRERGb05gUERERET9SJkVERMTmPJbGpIiIiIj4jTIpIiIiNlc28yjKpIiIiEgppUyKiIiIzXnKaC5FmRQREREplZRJERERsbmy+sRZdVJERERsTg9zExEREfGjMpNJ6XpVZ54ePQyn08GXM2bzwX+neW1v1KQBL705nJatm/PW2El8PPHTAEVaMtpd2Z57Rw7B4XSw6LOFfPnuF17b6zSuy8Pj/4/GrRoz/bWpfDPl6/xtf7u7L9fe2gtjYOHMBcz5YLa/wy+2jt07MHTkUJxOB/Nmzufzd//ntb1e47o8+vqjNGnVhE9e+4QvJn8JQN0L6vDsu8/kl4usH8W016fx9Qff+DP8YqvT/WI6vzgIh9PBtplL2PDOHK/t9a9tT4cn/oHlsfC43KwYOZ34VdsBuOie3jS/tTtYFilbo/nlsSm4j+UEoBbnrtWVbRk44m4cTgdLZ/3A3Ilfe23v3O9yrh/6dwCOZR5l6vApHNiyj6BywTwz6yWCygXjdDpZPe93vpkwKxBV8JnhY95g6W8rCQutzjfTJwU6nBJ38ZXtGPRC7rlf8tli5pxw7i/rfwV/G9ofgKzMLD5+bgr7t+wlLCqcoRMeplpEKJbHw0+fLmLBR98HoAa+UVYHzp6yk2KMmWZZ1iBjzCOWZb3pz6DOlsPhYPi4x7n3nw8TF5PArAUf8dOCX9i9fW9+mUNp6Yx77g16XHdl4AItIQ6Hg/tG388Ltw0nOTaZ8XMmsHLRCg7sOJBf5kjaYd57YTKde3X22rd+swZce2svHu/zKK6cHEZOG8XqH1YTuzfG39U4Zw6HgwdHP8gzA58lKTaJ/373JssXrWD/jv35ZdLTDjPxhUlc1quL177Ruw/yQO+H8o8zY9U0fpu/zK/xF5dxGC4bfSfzB44jIzaFvt+PYv/CNaTtOH4OY379k/0L1wIQemE9ekz8N192f5KKkaFcdPe1fNnjKdxZOVw18d9c0LczO/73S6Cqc9aMw8GgUfcy/vZRpMQlM2L2K6xbtIqYndH5ZZIOJDBuwPNkpmfQuns77hw7lNH9n8F1LIdXB47kWGYWziAnz3wxmg1L1rL7jx0BrFHJ6n99Twbe1JdnXxof6FBKnHE4uPOlexl324ukxCUzavarrFm8ipgdx8994oF4Rv8z99xf3L0dd48dysj+T+Nxe/h09Cfs3bSb8pXK89J349n463qvfaV4jDG9gTcBJ/C+ZVnjTth+G/BU3uIR4H7Lstaf7pinu93TwRjTALjbGBNqjAkr+Dr3apS81u1bsn9PNNH7YnDluJj3zSJ69L7Cq0xKUiqb1m3BleMKUJQlp2nbZsTtjSV+fzyuHBe/zFlKp2u9OyOHkg+xc8MOXC631/q6Teuyfe1WsrOO4XF72LR8E517e/8hL+2at21GzN4Y4vbH4cpxsWT2z3Q5Sf23r99+2vPdtltbYvfFknAwwdchl6iIto1J3xvP4f2JeHLc7P52OfWv7eBVxpV5LP/n4ArloMAjs02QE2f5EIzTQVCFEDLjU/0We0m4oG0TEvbFkXggHneOi5VzfqXdtZd4ldm5dhuZ6RkA7Fq7nbDI8PxtxzKzAHAGOQkKCipzT8Hq2LY11apWCXQYPtG4bRPi98bmn/vlc36lQ89OXmV2rDl+7neu3U5YVO65T0tIZe+m3QBkZWQRszOasFrhlBWWj/+diTHGCbwDXAe0BG41xrQ8odge4ErLsi4GXgKmnOm4p7vdMwmYD1wArAGM1/uRu75UqBkZQVzM8T808TEJtG5/UQAj8q3wyHCSYhLzl5Njk2jWtnmR9t2/bR+3P3EHVapX4VhWNh2u6sjODfb6FBkeWYPEAvVPik2iRbui1b+g7n2vZMm3P5dkaH5RMSqUjNiU/OXMuBQi2jUuVK5B7450fPqfVKhRlYV3jM8rm8qmyXO5ZcWbuLKyObh0IweXbvJb7CUhtFYYKTFJ+cspsSk0btv0lOWvGHA1G5f8kb9sHA5GfvcqNRtE8uO0+exeZ6/r/3wWGhlOSmxy/nJKbDKN25363He/5Ro2FDj3f6lRN4IGFzVi17rtPonzPNUJ2GlZ1m4AY8xnQD9g818FLMsqmLZeDtQ900FPmUmxLOsty7IuBD60LOsCy7IaFXidtoNijBlijFltjFmdctT3n1KNMYXWlbEPR94KVxeriF8uFb0zmq8mfsGLM15i5LQX2btlDx63+8w7liInOd2c7XdrBQUH0bnnpSz93j63OY47yfV+kvrvm7+aL7s/yeLBE2j/xD8ACKlWkfrXtufzLsOY2eHfBFcoR+Mbu/o64JJ1st/3U1wALbq04vIBV/P5uONj1CyPhxeuf5xHuwyhUZum1GlWz2ehSsk6ya/+KRv7C7u04soBV/PZ2Kle68tVLM8jk55k+qgPOXrkaInHGCgeH7+KoA5woMBydN66UxkMzDvTQc84u8eyrPvPGFrhfaZYltXRsqyOYRVqnu3uZy0+NoHI2sf/n1q1a5IYl3iaPewtOTaZGrUj8pfDo2qQkpBymj28LZ61iEdv+D+evflpDqcdJmaPfcajQG7mJKJA/WtE1SA5Pvk0exR2yVUd2blpF2lJaSUcne9lxqZQKer4HdeKkWFkxp36lk3cim1UbVCTcqGVqd2tFYcPJJKVchjL5WbvvNXU6nDqT6KlUWpcMmG1a+Qvh0WFkXaS679uiwbcNe5+3rp3HBlpRwptP5qeybblm2h9ZTufxislJyUuOf/2DUBYVDip8YXPfb0WDbjnlQeYcM9YjhQ4984gJ49MeoJl3yxl9fwVfom5rCiYfMh7DTmxyEl2O2kX0hhzFbmdlKdOtr2gMjEFedMfW6h/QT3q1I8iKDiI6/r35KcFdvyEXDQ71m8nqlFtatarRVBwEJf3uYKVi4r+C1ctvBoANWpH0KV3F5bOttctj23rt1OnYW1q5dW/e98rWb5o+Vkdo3u/7iz5dolvAvSxxPW7qdooksr1InAEO7mgX2f2L1rrVaZKw1r5P4e3aogjJIhjqUfIiEmmZrsmOMuHAFC720Wk7Tzo1/iLa8/6ndRsGEWNujVxBgfRqU83/li02qtMWO0aPDTpCd4b9hbxe2Lz11cJq0qFqhUBCC4XQsuuFxO7y171P5/tXr+TyEZRRNTLPfed+3Rj7aJVXmXCa9fg/yY/yaRhbxJX4NwD3PPqg8TsPMi8971nw5UFlmX5+pWffMh7nTieJBoomJasCxT6BGyMuRh4H+hnWdYZP12WiSnIbrebMc+MZ/Jnb+J0Ovh65nfs2raHf96ROwXx86lfEx4RxqyFH1O5SiU8Hg+3D7mFfpffQsaRzABHf/Y8bg9Tnp/EyGmjcDgd/DBrEQe276f37dcBMH/6PKpHVOf17/5DxcoV8Xg89Bncj4euvp+jR47y1ORnqRpaBVeOm8nPTyLjUEaAa3R2PG4P7zw/kTHTR+NwOlk4ayH7tu/nhtuvB+D76XMJjQjlv9+/RcXKFbE8HvoP7s+QHveReSSTcuXL0f7ydrz59FsBrsm5sdwefn/+E3rPeBLjcLB91s+kbT9Ii9t7ALB1+o80uv4SmtzUDY/LjTsrm5/ufxuAxD92sWfuSvrPH43lcpP85z62zvgpkNU5ax63hxkj3uexqc/jcDr45fMfidlxgO63XQvAkhkL6ffwzVQOrcKg0fcC4Ha5GdX3KarVDOWe1x/C4XBiHIZV3y9j/Y9rAlmdEvfEC+NY9ccG0tLSubr/7TwweBA39ekV6LBKhMft4ZMR7/Pk1BE4nA5+/vwHDu44QI+8c//jjIX8/ZF/Ujm0Cv96KfeDvtvtZkSfJ2nWsQWX39Sd/Vv28vLc1wH4/LUZrP9p7Sn/Pzkrq4CmxphGwEHgFmBgwQLGmPrAV8Agy7KKNCDIFHUsw7lqVatzmR4ecjqNy9U4c6EyLMuy11iXkvZPq+zMHDgXvwaVnfv952LK6tcCHULA3NXh8UCHEHDT93110iE0vtKv/t98+rf22/3fnbE+xpjrgf+QOwX5Q8uyXjbGDAWwLGuSMeZ94CZgX94uLsuyOp7umGUikyIiIiKBZVnWXGDuCesmFfj5HuCeszmmOikiIiI2p+/uEREREfEjZVJERERsrihPhbUjZVJERESkVFImRURExObK6rcgK5MiIiIipZIyKSIiIjbn62eeBYoyKSIiIlIqKZMiIiJic2X1OSnqpIiIiNicpiCLiIiI+JEyKSIiIjanKcgiIiIifqRMioiIiM1pCrKIiIiIHymTIiIiYnMakyIiIiLiR8qkiIiI2JyekyIiIiLiR8qkiIiI2JxHs3tERERE/EeZFBEREZsrm3kUZVJERESklFImRURExOb0nBQRERERP1ImRURExOaUSRERERHxI2VSREREbK6sfguyzzsprctH+vq/KNUm9TgS6BACJm19oCMIrMzDKYEOIaDu23d+XwA5HR4PdAgB89Ga8YEOQcoIZVJ86HzuoIiIiP+U1TEp6qSIiIjYnL5gUERERMSPlEkRERGxubI6cFaZFBERESmVlEkRERGxubI6cFaZFBERESmVlEkRERGxOY1JEREREfEjZVJERERsTmNSRERERPxImRQRERGb0xNnRURERPxImRQRERGb82h2j4iIiIj/KJMiIiJicxqTIiIiIuJHyqSIiIjYnMakiIiIiPiRMikiIiI2pzEpIiIiIn6kTIqIiIjNaUyKiIiIiB8pkyIiImJzZXVMijopIiIiNqfbPSIiIiJ+pEyKiIiIzZXV2z3KpIiIiEippEyKiIiIzVmWJ9Ah+IQyKSIiIlIq2TqT0ubKdtzxwj04nA5++mwRsyd+5bW9a/8r6Dv0RgCyMrP44LlJ7N+yl7CoGjww4RGqR1TH8lj88OlC5n/0XSCqcM6CWl1C+YEPgMNBztJ5HJv7WaEyzuZtqDDwfnAGYR0+RMYrj+VuqFCJinc9hqNuQ7Asjn44HveuLf6tQDGVv+wSwh5/AJwOjnw9j/SPvetfrkMbar4xCldMLACZP/7KofemA2AqVyJ8xGOENG4IWCS9OJ7sDfaqf6XLO1Br+H0Yp4O0zxeQPOV/XtsrdmpN3UkjyImOA+DwwmUkvT2ToMga1H7tMYIiQsFjkTprPqmffBuIKpy1CW+M4rrePcg8epTBg4fxx7pNhco0bFiPT6e/S2hoKH+s28id/3qYnJwcmjdvzAfvTaBdu1Y8P+IV3pgwOX+fatWqMmXyeC66qDmWZXHvvY+xfMUaf1btrFx8ZTsGvXA3DqeDJZ8tZs7Er722X9b/Cv42tD+Q2+59/NyUvHYvnKETHqZaRCiWx8NPny5iwUffB6AGvjV8zBss/W0lYaHV+Wb6pECH4zeeMjomxbadFONwcNdL9zHmthdIjkvm5dmvsWbxSg7uiM4vk3AgnlH/fI6M9AzadG/PvWMf4Pn+T+Jxu5k++iP2btpN+UrlGfPd62z8dZ3XvqWacVB+0L/JGP8UVkoilUe8Q866ZXhi9h8vU6ESFQY9TMYbz2ClJGCqVD++6bYHydm0ipx3R4EzCELK+b8OxeFwEPbUv0l44Clc8YlETX+Hoz8vI2fPfq9iWes2kvjI8EK7hz3xIFnLVpH05CgICsKUt1/9I0c+wP5/PUdOXBKNvvwPh39cTvbOA17FMlf/SfSQkd77ut0kjH2frM27cFSqQMOv3yLjt7WF9i1truvdg6ZNGtGiZTcu7dSed94ey2Xd+hQqN3bMc/znrff4/PPZvPP2OO6+61YmT5lKSkoa/zfsefr1611onwlvjGLBgp8YcMsQgoODqVixgj+qdE6Mw8GdL93LuNteJCUumVGzX2XN4lXEFGi7Eg/EM/qfz5OZnsHF3dtx99ihjOz/NB63h09Hf5Lf7r303Xg2/rrea9+yoP/1PRl4U1+efWl8oEOREmDb2z1N2jYlbm8sCQficee4+H3Or3TsealXmR1rtpGRngHAzrXbCIsKByAtIZW9m3YDkJWRxcGd0YTVCvdvBYrBeUFzPAkxWImx4HaRs3IJwe26epUJ6Xw1OWt/xUpJAMA6nJa7oXxFgpq1JmfpvNxltwuOZvgx+uILadUcV3QMroOx4HKRsWAJFbp3PfOOgKlUkfLtW3Pkm7z6u1xYR+xV/woXNyN7Xww5B+Igx0X690upcnWXIu3rSkwla/MuADwZR8netZ/gWjV8GW6J6NOnF9NmfAHAipVrqVa9GpGRNQuVu6p7V778Mjc7MG3a/+jXtxcAiYnJrF6znpycHK/yVapU5vJul/LhRzMByMnJ4dChdF9WpVgat21C/N5YEvPaveVzfqVDz05eZXas2UZmfru3/ZTtXozN2r2i6ti2NdWqVgl0GH5nWZZPX4FSpEyKMebRk6w+BKyxLGtdiUZURKGRYSTHJuUvJ8cm06Rd01OW737LNaxbsrbQ+hp1a9LwogvYuW67T+L0BRNaI7/zAeBJScTZuIVXGUdkHXAGUemp1zHlK3Bs0dfkLFuEIyIKz+FDVBj8BM56jXHv287RGe9Cdpa/q3HOgiJq4Io7Xn93QiIhrVoUKleudUuiPpuMOzGZ1AmTydm9j6A6UbhTDxE+8glCmjXm2JbtpL72LlaWjeofGY6rwLWfE5dEhTbNC5Wr0LYFjWa/jSshhfhx75O90zvTFFynJuVbNubo+q0+j7m46tSOJPpATP7ywehY6tSOJK7AdRAeHkpa2iHcbjcA0QdjqV0n8rTHveCCBiQlJfPB+xO4+OKWrF27gWGPjiAz86hvKlJMoZHhpMQm5y+nxCbT+Azt3oYlfxRaX6NuBA0uasQuG7V7cn4qaialIzAUqJP3GgJ0B94zxjzpm9BOz2AKrzxFZ69ll1ZcNeAaZo6d6rW+XMXyDJv0FFNHfcDRI6WzUTq5ItTd6cTZsBkZE54j4/WnKdf3Nhy16mCcTpwNmpL90xyOjByKdSyLcjfc4peoS4w5c/2zt+7g4A0Dib3lPtI/+4aIN17M3dXpJKRFUw5/MYfYgUOxjmZR9S6b1f+k59/7DcjavJOd3f/Fnr4PkTJtNvUmPu99hIrlqfP2c8S/PAWPDa59c5JzfuKnu6KUOVGQ00m7dq2ZPHkql3TqRUZGJk89+VDxgvWhk5z5U7Z7F3ZpxZUDruazk7R7j0x6kumjPrRZuyen48Hy6StQitpJCQfaW5b1mGVZj5HbaYkArgD+dWJhY8wQY8xqY8zqnUf2llSsXlLikgmPOp6mDo8KJzU+pVC5+i0aMOSVhxh/z1iOpB3OX+8McjJs0lP89s3PrJq/3Ccx+oqVmogJO57qdoRFYKUle5dJScK1cRVkZ2EdSce9bSOOeo3xpCRipSbi3p376Tln1VKcDU79Saw0ciUkElQg1e+sGYE78YT6Z2RiHc3NjmT9thITFISjelVcCYm4ExLJ3pRb/8wflhLSwmb1j0siqMC1HxxZA1eC97XvOXIUKzO3/hk/r4agIJyhVXM3Bjmp+/ZzpM9ewuGFy/wW99m6f+idrF61kNWrFhITG0fderXzt9WpG0VMbLxX+aSkFKpXr4bT6QSgbp0oYmO8y5wo+mAs0dGxrFyVm2346qvvade2dQnXpOSkxCXn374BCDtFu1evRQPueeUBJtwzliNpR/LXO4OcPDLpCZZ9s5TV81f4JWaR4ihqJ6U+kF1gOQdoYFnWUeDYiYUty5piWVZHy7I6NqncsPhRnsSu9TuIbBRFRL2aOIOD6NKnG2sWrfQqE167BsMmP807wyYQtyfGa9uQVx8iZmc0c9+f7ZP4fMm9ZxvOmnUwNSLBGURwp+7k/OH9xybnj2UENWsFDgeElMN5QQs8sfux0lPxpCTiiKwLQFDL9nhi9gWiGucs+89tBNWrQ1DtSAgKolKv7hz92bv+jvDQ/J9DLmoOxoEnLR1Pciqu+ESCGuTWv3yn9uTssVf9j27cTkjD2gTXrQXBQVS94QoO/+Dd0XbWOF7/8hc3wzgM7tTcsRZRY/6P7F0HSPnIe1ZIaTNx0id0vORaOl5yLbNnL2DQbf8A4NJO7Uk/lO51q+cvS35exk033QDAoEE3M3vOwtP+H/HxiURHx9CsWWMAevToxpYtpfcWyO71O73avc59urF20SqvMuG1a/B/k59k0rA3idsT67XtnlcfJGbnQea9P8efYYsflNUxKaYo/7kx5nng78BfcxX7ALOB14EplmXddqp9b23Q32e1a3tVB+4YcTcOp5Mlny/mm7e/4JrbcgfKLZ6xgHtfeZBO13UhKToRAI/bzXN9Hqd5xwsZ+eVY9m/Zi8eTG96s16az7qeSnXY4qceRMxc6R0EXd6L8rXlTkH+Zz7HvPiWk+98AyF6SO506pPc/CenWCywP2Uvnkb0od4q2o15jKtz1KCYoGE9iLJkfvAaZJR9r2voSP2S+8l075U5Bdjg4Mns+6R98SuWbcut/5MvvqDKgH5X/0Qfcbqxj2aS+PpFjGzYDENysMeEjHsUEB+OKjiV55Gt4Dpd8/TMPh5T4Mf9S6cqO1HoubwryFwtJnjiL6rdeD0DazLmE3v43QgfegOXKrX/8mPc4+scWKnRoScPPxpO1dQ/kPfwp4fVPcrMtJaz1vpK9AN5682V6XdudzKNHueeeR1mzdgMAc76dypChTxAbG0+jRvXzpiBXZ936P7njzn+TnZ1NrVoRrPh9HlWrVsbj8XDkSCat23Tn8OEjtGlzEZMnvUZISDB79uxn8D2PkpZ2qNjx3hJ16ZkLnYM2V7Xn9hG5U5B//vwHZr/9JT1uuxaAH2cs5J5XHuCS6zrnt3tut5sRfZ6kWccWjPhyDPu37MXKa/c+f20G638qPFavuD5aE7iZNU+8MI5Vf2wgLS2d8LDqPDB4EDf16eX3OIJrXHDSu3O+Uif0Ip/2JA6m/unX+vylSJ0UAGNMB6AbubdFf7Usq0itmi87KaWdLzspduDLTood+LKTYgcl3UmxG191UuwgkJ2U0sLfnZSo6i19+rc2Nm1zQDopRX5OimVZa4DS+4QjERERKVNs+zA3ERERyaVvQRYRERHxI2VSREREbC6QM3B8SZkUERERKZWUSREREbE5fQuyiIiIlEq63SMiIiLiR8qkiIiI2JxHmRQRERER/1EmRURExOY0JkVERETEj5RJERERsbmyOgVZmRQREREplZRJERERsTmNSRERERHxI2VSREREbE7PSRERERHxI2VSREREbM7S7B4RERER/1EnRURExOY8luXTV1EYY3obY7YZY3YaY54+yXZjjHkrb/sGY0z7Mx1TnRQREREpFmOME3gHuA5oCdxqjGl5QrHrgKZ5ryHAxDMdV2NSREREbK4UPCelE7DTsqzdAMaYz4B+wOYCZfoBU63cYJcbY6obY6Isy4o91UGVSREREZHTMsYMMcasLvAackKROsCBAsvReevOtowXZVJERERsztezeyzLmgJMOU0Rc7LdzqGMF2VSREREpLiigXoFlusCMedQxos6KSIiIjZnWZZPX0WwCmhqjGlkjAkBbgFmn1BmNnBH3iyfzsCh041HAd3uERERsb1AD5y1LMtljHkIWAA4gQ8ty/rTGDM0b/skYC5wPbATyATuOtNx1UkRERGRYrMsay65HZGC6yYV+NkCHjybY6qTIiIiYnMBn4DsIxqTIiIiIqWSCfR9LF8zxgzJmzp1XlL9z9/6n891B9Vf9T+/619WnA+ZlBMfOHO+Uf3PX+dz3UH1V/3F9s6HToqIiIjYkDopIiIiUiqdD52U8/2epOp//jqf6w6qv+ovtlfmB86KiIiIPZ0PmRQRERGxIXVSyihjTENjzKZAxyGBZ4wZaYx5PNBxiP8YYx42xmwxxswIdCwixaEnzoqIlD0PANdZlrUn0IGIFEeZzqQYY74xxqwxxvxpjDkf58wHGWM+McZsMMZ8YYypGOiA/MUYc0devdcbY6YFOh5/M8Y8Z4zZZoxZDDQPdDz+Zoy53Riz0hizzhgz2RjjDHRM/mKMmQRcAMw2xgwLdDz+Zox53hiz1RizyBgzU1lEeyvTnRTgbsuyOgAdgYeNMeGBDsjPmgNTLMu6GEgn99NVmWeMuQh4DuhhWVYb4JEAh+RXxpgO5H5NejvgRuCSwEbkX8aYC4EBQFfLstoCbuC2gAblR5ZlDQVigKssy5oQ6Hj8yRjTEbiJ49d+x8BGJMVV1jspDxtj1gPLgXpA0wDH428HLMv6Le/n6UC3QAbjRz2ALyzLSgKwLCslwPH42+XA15ZlZVqWlQ7MDnRAfnY10AFYZYxZl7d8QUAjEn/pBnxrWdZRy7IOA3MCHZAUT5kdk2KM6Q5cA3SxLCvTGLMEKB/ImALgxPnl58t8c8P5U9dTOZ/rb4BPLMt6JtCBiN+ZQAcgJassZ1KqAal5HZQWQOdABxQA9Y0xXfJ+vhX4NZDB+NEPwD//ur1njAkLcDz+thT4uzGmgjGmCtAn0AH52Q/AP4wxNSH3/BtjGgQ4JvGPX4E+xpjyxpjKwA2BDkiKp8xmUoD5wFBjzAZgG7m3fM43W4A7jTGTgR3AxADH4xeWZf1pjHkZ+NkY4wb+AP4V2Kj8x7KstcaYWcA6YB/wS2Aj8i/LsjYbY4YDC40xDiAHeJDc90LKMMuyVhljZgPryT3fq4FDgY1KikNPnBURkTLDGFPZsqwjebMZlwJDLMtaG+i45NyU5UyKiIicf6YYY1qSOwbxE3VQ7E2ZFBERESmVyvLAWREREbExdVJERESkVFInRUREREoldVJERESkVFInRUREREoldVJERESkVPp/ez9+pZmJj3EAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 720x648 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10,9))\n",
    "labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g']\n",
    "sns.heatmap(scores, xticklabels=labels, yticklabels=labels, annot=True)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "简化写法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Asking to truncate to max_length but no maximum length is provided and the model has no predefined maximum length. Default to no truncation.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sentence embeddings:\n",
      "tensor([[-0.3931,  0.0389,  1.9874,  ..., -0.6094, -1.0946,  0.3265],\n",
      "        [ 0.0615,  0.3274,  1.8332,  ..., -0.1299,  0.4609,  0.2404]])\n",
      "Cosine similarity between \"This is an example sentence\" and \"Each sentence is converted\" is: 0.578\n"
     ]
    }
   ],
   "source": [
    "from transformers import AutoTokenizer, AutoModel\n",
    "import torch\n",
    "from scipy.spatial.distance import cosine\n",
    "\n",
    "#Mean Pooling - Take attention mask into account for correct averaging\n",
    "def mean_pooling(model_output, attention_mask):\n",
    "    token_embeddings = model_output[0] #First element of model_output contains all token embeddings\n",
    "    input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()\n",
    "    return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)\n",
    "\n",
    "\n",
    "# Sentences we want sentence embeddings for\n",
    "sentences = ['This is an example sentence', 'Each sentence is converted']\n",
    "\n",
    "# Load model from HuggingFace Hub\n",
    "# tokenizer = AutoTokenizer.from_pretrained('sentence-transformers/bert-large-nli-stsb-mean-tokens')\n",
    "# model = AutoModel.from_pretrained('sentence-transformers/bert-large-nli-stsb-mean-tokens')\n",
    "\n",
    "\n",
    "tokenizer = AutoTokenizer.from_pretrained('sentence-transformers/bert-base-nli-mean-tokens')\n",
    "model = AutoModel.from_pretrained('sentence-transformers/bert-base-nli-mean-tokens')\n",
    "\n",
    "# Tokenize sentences\n",
    "encoded_input = tokenizer(sentences, padding=True, truncation=True, return_tensors='pt')\n",
    "\n",
    "# Compute token embeddings\n",
    "with torch.no_grad():\n",
    "    model_output = model(**encoded_input)\n",
    "\n",
    "# Perform pooling. In this case, max pooling.\n",
    "sentence_embeddings = mean_pooling(model_output, encoded_input['attention_mask'])\n",
    "\n",
    "print(\"Sentence embeddings:\")\n",
    "print(sentence_embeddings)\n",
    "\n",
    "# Calculate cosine similarities\n",
    "# Cosine similarities are in [-1, 1]. Higher means more similar\n",
    "cosine_sim = 1 - cosine(sentence_embeddings[0], sentence_embeddings[1])\n",
    "\n",
    "print(\"Cosine similarity between \\\"%s\\\" and \\\"%s\\\" is: %.3f\" % (sentences[0], sentences[1], cosine_sim))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SimCSE计算句子相似度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Cosine similarity between \"There's a kid on a skateboard.\" and \"A kid is skateboarding.\" is: 0.943\n",
      "Cosine similarity between \"There's a kid on a skateboard.\" and \"A kid is inside the house.\" is: 0.439\n"
     ]
    }
   ],
   "source": [
    "from transformers import AutoModel, AutoTokenizer\n",
    "import torch\n",
    "from scipy.spatial.distance import cosine\n",
    "\n",
    "import os\n",
    "\n",
    "os.environ[\"KMP_DUPLICATE_LIB_OK\"] = \"TRUE\"\n",
    "\n",
    "tokenizer = AutoTokenizer.from_pretrained(\"princeton-nlp/sup-simcse-bert-base-uncased\")\n",
    "model = AutoModel.from_pretrained(\"princeton-nlp/sup-simcse-bert-base-uncased\")\n",
    "\n",
    "# tokenizer.save_pretrained(os.path.expanduser('~/Documents/Data/transformers_models/sup-simcse-bert-base-uncased'))\n",
    "# model.save_pretrained(os.path.expanduser('~/Documents/Data/transformers_models/sup-simcse-bert-base-uncased'))\n",
    "\n",
    "# Tokenize input texts\n",
    "texts = [\n",
    "    \"There's a kid on a skateboard.\",\n",
    "    \"A kid is skateboarding.\",\n",
    "    \"A kid is inside the house.\"\n",
    "]\n",
    "inputs = tokenizer(texts, padding=True, truncation=True, return_tensors=\"pt\")\n",
    "\n",
    "# Get the embeddings\n",
    "with torch.no_grad():\n",
    "    embeddings = model(**inputs, output_hidden_states=True, return_dict=True).pooler_output\n",
    "\n",
    "# Calculate cosine similarities\n",
    "# Cosine similarities are in [-1, 1]. Higher means more similar\n",
    "cosine_sim_0_1 = 1 - cosine(embeddings[0], embeddings[1])\n",
    "cosine_sim_0_2 = 1 - cosine(embeddings[0], embeddings[2])\n",
    "\n",
    "print(\"Cosine similarity between \\\"%s\\\" and \\\"%s\\\" is: %.3f\" % (texts[0], texts[1], cosine_sim_0_1))\n",
    "print(\"Cosine similarity between \\\"%s\\\" and \\\"%s\\\" is: %.3f\" % (texts[0], texts[2], cosine_sim_0_2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6688703894615173"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tokens = tokenizer([a, b, c, d, e, f, g],\n",
    "                   max_length=128,\n",
    "                   truncation=True,\n",
    "                   padding='max_length',\n",
    "                   return_tensors='pt')\n",
    "\n",
    "# Get the embeddings\n",
    "with torch.no_grad():\n",
    "    embeddings = model(**tokens, output_hidden_states=True, return_dict=True).pooler_output\n",
    "\n",
    "b_c = 1 - cosine(embeddings[1], embeddings[2]) # b_c:0.6\n",
    "b_c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-0.16888834536075592"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a_f = 1 - cosine(embeddings[0], embeddings[5]) # a_f:-0.1\n",
    "a_f"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.19932939112186432"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a_c = 1 - cosine(embeddings[0], embeddings[2]) # a_c:0.1\n",
    "a_c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.5386984944343567"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b_g = 1 - cosine(embeddings[1], embeddings[6]) # b_g:0.5\n",
    "b_g"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([7, 768])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "embeddings.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "# convert to numpy array from torch tensor\n",
    "embeddings = embeddings.detach().numpy()\n",
    "# calculate similarities (will store in array)\n",
    "scores = np.zeros((embeddings.shape[0], embeddings.shape[0]))\n",
    "for i in range(embeddings.shape[0]):\n",
    "    scores[i, :] = cosine_similarity(\n",
    "        [embeddings[i]],\n",
    "        embeddings\n",
    "    )[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.99999994,  0.08410864,  0.19932942,  0.16149577,  0.0628436 ,\n",
       "        -0.16888835,  0.15908465],\n",
       "       [ 0.08410864,  1.00000012,  0.66887045,  0.15511377, -0.04434279,\n",
       "        -0.08248205,  0.53869855],\n",
       "       [ 0.19932942,  0.66887045,  1.00000012,  0.31775126,  0.11580173,\n",
       "        -0.0993001 ,  0.57613033],\n",
       "       [ 0.16149577,  0.15511377,  0.31775126,  0.99999994,  0.22724755,\n",
       "         0.05825395,  0.21090063],\n",
       "       [ 0.0628436 , -0.0443428 ,  0.11580173,  0.22724755,  1.        ,\n",
       "         0.07467985,  0.01525629],\n",
       "       [-0.16888835, -0.08248205, -0.0993001 ,  0.05825395,  0.07467984,\n",
       "         0.99999994, -0.03223572],\n",
       "       [ 0.15908468,  0.53869843,  0.57613033,  0.21090065,  0.01525629,\n",
       "        -0.03223572,  1.00000012]])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "scores"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 展示SimCSE句子相似度结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<AxesSubplot:>"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x648 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "plt.figure(figsize=(10,9))\n",
    "labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g']\n",
    "sns.heatmap(scores, xticklabels=labels, yticklabels=labels, annot=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "本节完。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}